Fix NonlinearSolveAlg crashing/stalling with polyalgorithm inner solvers - #3959
Merged
ChrisRackauckas merged 2 commits intoAug 1, 2026
Merged
Conversation
singhharsh1708
force-pushed
the
fix-nonlinearsolvealg-polyalg-3859
branch
2 times, most recently
from
July 25, 2026 19:18
7dd8e8a to
4ec539e
Compare
singhharsh1708
force-pushed
the
fix-nonlinearsolvealg-polyalg-3859
branch
2 times, most recently
from
July 31, 2026 20:09
54a5ba9 to
49dec7d
Compare
NonlinearSolvePolyAlgorithmCache (RobustMultiNewton, FastShortcutNonlinearPolyalg, ...) keeps u/fu on the active branch cache instead of as top-level fields, so every raw cache.cache.u-style read in newton.jl threw a FieldError. Read the inner iterate and residual through NonlinearSolveBase.get_u/get_fu, which resolve to the active branch for polyalgorithm caches and are plain field reads otherwise. The nlstep solution no longer carries the inner trace: it only feeds nlprobmap, and polyalgorithm caches expose no accessor for a trace. A second bug lived upstream: the polyalgorithm cache's reinit! left force_stop/retcode set once any branch had converged, so every later step! short-circuited on not_terminated and silently reused a stale iterate. NonlinearSolveBase 2.39 resets both in reinit!, so no local reset is needed; the compat floor bump follows once it is registered.
singhharsh1708
force-pushed
the
fix-nonlinearsolvealg-polyalg-3859
branch
from
August 1, 2026 21:26
49dec7d to
68b360c
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the
FieldErrorcrash in #3859.NonlinearSolvePolyAlgorithmCache(RobustMultiNewton, FastShortcutNonlinearPolyalg) keepsu/fuon its active subcache, not at top level, so every rawcache.cache.u-style read in newton.jl threwFieldErrorthe moment a polyalgorithm was used as theNonlinearSolveAlginner solver. Itsreinit!also leftforce_stop/retcodeset after a branch converged once, so astep!-driven loop silently no-oped forever after and reused a stale iterate.Per review, both problems are fixed at the interface level in NonlinearSolve.jl#1115 (polyalg
get_u/get_fuaccessors plus theforce_stop/retcodereset inreinit!), merged and released as NonlinearSolveBase 2.39.0. This PR is just the consumer side: every polyalg-unsafe inner-cache read in newton.jl — the resize length check, the stale-Wrhs rescale from #4028, bothcompute_step!paths, and the nlstepbuild_solution— goes throughNonlinearSolveBase.get_u/get_fu. No local workaround remains. Top-level fields the polyalg cache genuinely has (retcode,stats,prob,alg) are read as before, andnot_terminatedonly touchesforce_stop/nsteps/maxiters, which are also top-level. The nlstepbuild_solutionno longer attaches the inner trace (no polyalg accessor exists; the transient solution only feedsnlprobmap). The compat floor is raised to"2.39", andget_u/get_fuare added to the QA non-public-import allowlist alongsidenot_terminated.Regression test
nsa_polyalg_tests.jlruns TRBDF2 and FBDF with aRobustMultiNewtoninner solver and checks both against the analytic solution of a stiff linear system to 1e-4, plus retcodes. Against the registered NonlinearSolveBase (pinned to the 2.39.0 floor): 8/8 new, and unchanged elsewhere — newton_tests 6/6, nsa_jacobian_reuse 17/17, nsa_matrixfree 14/14, nsa_smooth_est 10/10, nsa_sparse 10/10, nsa_stats 24/24, QA 16/16, all identical to master.The #3859 MWE (Robertson,
TRBDF2(nlsolve = NonlinearSolveAlg(RobustMultiNewton(autodiff = AutoForwardDiff()))),reltol=1e-6,abstol=1e-9) throwsFieldErroron master and returnsSuccesshere, withu(1e5) = [0.0178650, 7.2744e-8, 0.9821349]against a default-FBDFreference of[0.0178659, 7.2748e-8, 0.9821340](5e-5 relative). The active branch is TrustRegion, and the run is step-for-step identical toNonlinearSolveAlg(TrustRegion()).Scope: this fixes the crash, not every polyalgorithm.
FastShortcutNonlinearPolyalgno longer throws, but its leading branches are Jacobian-free quasi-Newton methods, which do not produce a usable stage step under the one-step!-per-outer-iteration driving mode; the integrator reportsUnstable/MaxItersrather than a wrong answer. Polyalgorithms combined with a matrix-freeW(linsolve = KrylovJL_GMRES()) are still refused atinitby NonlinearSolveBase, identically on master, because_nlalg_with_linsolvecannot push a linsolve into a polyalgorithm; the related SciML/NonlinearSolve.jl#1132 is still open. Both are better addressed by the #3817 redesign (drive inner solvers bysolve!per stage) than by more glue here.AI Disclosure
Claude assisted with this work.